package com.cloudminds.resttest.push;


import com.cloudminds.resttest.api.CallManager;
import com.cloudminds.resttest.api.RestApi;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.json.JSONException;
import org.json.JSONObject;


/**
 * Created by zoey on 2018/4/19.
 */

public class PushClient {

    private MqttAsyncClient mqttClient;
    private MqttConnectOptions options;
    private static String TOPIC = "rcuid";
    private static String TOPIC2 = "username";
    private String clientId ;
    private PushClient instance;
    public static String USERNAME = "hari";
    public static String PASSWORD = "123456";
    private static final String TAG = "PushClient";
    private CallManager callManager;
    private RestApi rest;

    private boolean isConnecting = false;

    public PushClient(String rcuId){
        initOptions();
        clientId = rcuId;
        System.out.print(clientId);
        TOPIC = "hello";
        TOPIC2 = "hello2";
        try {
            if (!clientId.isEmpty()){
                mqttClient = new MqttAsyncClient(getMqttServer(), clientId, new MemoryPersistence());
                mqttClient.setCallback(mqttCallback);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("create mqtt client error");
        }
        instance = this;
    }

    public PushClient(CallManager callManager){

        initOptions();
        this.callManager = callManager;

        try {
            clientId = callManager.getRcuId();
        }catch (NullPointerException e){
            e.printStackTrace();
        }

        TOPIC = "hello";
        TOPIC2 = "hello2";

        try {
            if (!clientId.isEmpty()){
                mqttClient = new MqttAsyncClient(getMqttServer(), clientId, new MemoryPersistence());
                mqttClient.setCallback(mqttCallback);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("create mqtt client error");
        }

        instance = this;
    }

    private void initOptions(){
        options = new MqttConnectOptions();
        options.setCleanSession(false);
        // 设置连接的用户名
        options.setUserName(USERNAME);
        // 设置连接的密码
        options.setPassword(PASSWORD.toCharArray());
        // 设置超时时间 单位为秒
        options.setConnectionTimeout(10);
        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
        options.setKeepAliveInterval(10);
        options.setAutomaticReconnect(false);
    }

    private final MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {
            System.out.println("mqtt connection lost:" + cause);
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            System.out.println("---receiveMsg--- topic:" + topic + ",msg:" + message.toString());
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            System.out.println("Msg delivery completed:"+token.getMessageId());
        }
    };

    public PushClient getInstance(){
        return instance;
    }


    /**
     * 连接服务器
     * MqttService有自己的重连机制，在断线情况下会重连，但是首次连接失败后，需要再调用connect方法
     */
    public void connect() {

        try {
            isConnecting = true;
            if (null == mqttClient){
                System.out.println("can not connect due to mqttClient is null");
                isConnecting = false;
                return;
            }
            if (mqttClient.isConnected()){
                System.out.print("Mqtt is connected, so ignored!");
                isConnecting = false;
                return;
            }

            if (getMqttServer().equalsIgnoreCase("")){
                System.out.print("Mqtt server is empty!");
                isConnecting = false;
                return;
            }

            try {
                mqttClient.setCallback(mqttCallback);
                mqttClient.connect(options,null,iMqttActionListener);
            } catch (MqttException e) {
                e.printStackTrace();
                isConnecting = false;
            }
        } catch (Exception e){
            System.out.print("PushClient: "+ "connect "+ e.getMessage());
            isConnecting = false;
        }
    }



    private String getMqttServer(){
        String savedServer = PushParams.getPushServer();
        if (!savedServer.isEmpty()){
            savedServer = "tcp://"+savedServer;
        }
        System.out.println("mqtt server:"+savedServer);
        return savedServer;
    }

    private final IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken asyncActionToken) {
            System.out.println("Push server connected");
            isConnecting = false;
        }

        @Override
        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
            System.out.println("Push server connect error:" + exception);
        }
    };



    /**
     * 断开服务器链接
     */
    public void disConnect() {
        if (null == mqttClient) {
            return;
        }
        try {
            mqttClient.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
        System.out.println("Push server disconnected");
    }

    public void destory(){
        disConnect();
    }

    /**
     * 发布消息
     * @param msg   消息内容
     */
    public void push2AiAs(final String msg) {

        //System.out.println("Publish message to aias");
        if (null==mqttClient || !mqttClient.isConnected()){
            System.out.println("Mqtt is not connected");
            if (!isConnecting){
                connect();
            }
            return;
        }
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setPayload(msg.getBytes());
        mqttMessage.setRetained(false);
        mqttMessage.setQos(2);  //* @param qos   0：最多一次的传输；1：至少一次的传输；2： 只有一次的传输
            // System.out.print("人脸发送成功。。。。");
        try {
            IMqttDeliveryToken s = mqttClient.publish("appPush2Aias", mqttMessage);
            System.out.print("人脸发送成功。。。。");
        } catch (MqttException e) {
            e.printStackTrace();
        }

    }

    /**
     * 上报roc的接口
     * @param msg
     */
    public void push2Roc(final JSONObject msg){

        System.out.println("push message to roc");
        if (null==mqttClient || !mqttClient.isConnected()){
            System.out.println("Mqtt is not connected");
            if (!isConnecting){
                connect();
            }
            return;
        }
        String mqMsg = "";
        JSONObject object = new JSONObject();
        try {
            object.put("id","push");
            object.put("seq", System.currentTimeMillis());
            object.put("sid", callManager.getSessionId());
            object.put("from",callManager.getRcuId()+"|"+callManager.getRcuId());
            object.put("to","roc");
            object.put("tenantCode", "cloudminds");
            object.put("timestamp",String.valueOf(System.currentTimeMillis()));
            object.put("message",msg);
            mqMsg = object.toString();
        }catch (JSONException e){
            e.printStackTrace();
        }

        //System.out.println("mq msg: "+mqMsg);
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setPayload(mqMsg.getBytes());
        mqttMessage.setRetained(false);
        mqttMessage.setQos(2);  //* @param qos   0：最多一次的传输；1：至少一次的传输；2： 只有一次的传输
        try {
            mqttClient.publish("appPush2Roc", mqttMessage);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

}
